﻿using System;
using System.Windows.Forms;
using Excel = Microsoft.Office.Interop.Excel;

namespace QAToolsAddin {
    public enum Content { Text, Value, Formula }

    static class ExcelArray<T> {

        public static T[,] Create(int nbRow, int nbColumn) {
            return (T[,])Array.CreateInstance(typeof(T), new[] { nbRow, nbColumn }, new[] { 1, 1 });
        }

        public static T[] Create(int nbRow) {
            return new T[nbRow + 1];
        }

        public static T[,] Get(Excel.Range range, Content content) {
            switch (content) {
                case Content.Formula:
                    return Get(range.Formula);
                case Content.Value:
                    return Get(range.Value);
                case Content.Text:
                    return Get(GetTextArray(range));
                default:
                    return null;
            }
        }

        public static T[,] Get(object value) {
            if (value != null && value.GetType().IsArray)
                return (T[,])value;
            var array = (T[,])Array.CreateInstance(typeof(T), new[] { 1, 1 }, new[] { 1, 1 });
            array[1, 1] = (T)value;
            return array;
        }

        private static object[,] GetTextArray(Excel.Range range) {
            if (range == null)
                return null;
            bool toogleRefresh = range.Application.ScreenUpdating;
            if (toogleRefresh)
                range.Application.ScreenUpdating = false;
            var clipBackup = Clipboard.GetText();
            range.Copy(Type.Missing);
            var data = Clipboard.GetText();
            range.Application.CutCopyMode = 0;
            if (!string.IsNullOrEmpty(clipBackup))
                Clipboard.SetText(clipBackup);
            if (toogleRefresh)
                range.Application.ScreenUpdating = true;
            if (string.IsNullOrEmpty(data))
                return null;
            string[] rows = data.TrimEnd('\r', '\n').Split(new string[] { "\r\n" }, StringSplitOptions.None);
            object[,] array = null;
            int nbRow = rows.Length;
            int nbCol = 0;
            if (nbRow != 0) {
                for (int r = 0, ri = 1; r < nbRow; r++, ri++) {
                    var row = rows[r].Split('\t');
                    if (r == 0) {
                        nbCol = row.Length;
                        array = ExcelArray<object>.Create(rows.Length, nbCol);
                    }
                    for (int c = 0; c < nbCol; c++)
                        array[ri, c + 1] = row[c];
                }

            }
            return array;
        }
    }

    static class Array<T> {
        public static T[] Join(T[] a, T[] b) {
            var table = new T[a.Length + b.Length];
            for (int i = 0; i < a.Length; i++)
                table[i] = a[i];
            for (int i = 0, ii = a.Length; i < b.Length; i++)
                table[ii++] = b[i];
            return table;
        }

    }
}
